// Holds data points while tracking is happending
// I think we want to just store it in this temporarily, and then move them to the result after all the needed info is gathered

package edu.berkeley.drivingbuddy;

import android.location.Location;

import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;

public class DataPointTracker {
	public interface DataPointListener {
		// a value of 0 means perfect driving, a value of 1 means we are going to die
		public void processRecentDrivingScore(float score);
	}

	private DataPointListener mListener;
	private List<LocationDataPoint> mLocations;
	private List<AccelerationDataPoint> mAccelerations;

	public DataPointTracker(DataPointListener listener) {
		mListener = listener;
		mLocations = new ArrayList<LocationDataPoint>();
		mAccelerations = new ArrayList<AccelerationDataPoint>();
	}

	public synchronized void addDataPoint(LocationDataPoint locationDataPoint) {
		mLocations.add(locationDataPoint);
	}

	public synchronized void addDataPoint(AccelerationDataPoint accelerationDataPoint) {
		boolean shouldStore = true;
		if (mAccelerations.size() > 0) {
			long lastTimestamp = mAccelerations.get(mAccelerations.size() - 1).getTime();
			long minimumDiff = 250;
			if (accelerationDataPoint.getTime() - lastTimestamp < minimumDiff) {
				shouldStore = false;
			}
		}

		if (shouldStore) {
			mAccelerations.add(accelerationDataPoint);
			float relativeScore = accelerationDataPoint.getAcceleration() / 350.0f;
			mListener.processRecentDrivingScore(relativeScore);
		}
	}

	public int getScore() {
		// horrible driver: 30% over 200
		// perfect driver: 
		long totalScore = 0;
		for (AccelerationDataPoint dataPoint : mAccelerations) {
			float acceleration = dataPoint.getAcceleration();
			if (acceleration < 100)
				totalScore += 100;
			else if (acceleration < 120)
				totalScore += 80;
			else if (acceleration < 170)
				totalScore += 70;
			else if (acceleration < 220)
				totalScore += 60;
			else if (acceleration < 280)
				totalScore += 50;
			else if (acceleration < 400)
				totalScore += 25;
		}
		int finalScore = (int) totalScore / mAccelerations.size();
		return finalScore;
	}

	// can be used to get the incremental scores
	// good for the graph on the results page
	public List<Integer> getScoreHistory() {
		List<Integer> history = new LinkedList<Integer>();
		for (AccelerationDataPoint dataPoint : mAccelerations)
			history.add((int) dataPoint.getAcceleration());

		return history;
	}
	
	public Location getStartLocation() {
		return mLocations.get(0).getLocation();
	}
	
	public Location getEndLocation() {
		return mLocations.get(mLocations.size() - 1).getLocation();
	}

}
